package com.gxp.system.service.impl;

import com.gxp.common.constant.AutomationConstants;
import com.gxp.common.constant.UserConstants;
import com.gxp.common.core.domain.entity.SysUser;
import com.gxp.common.core.text.Convert;
import com.gxp.common.utils.DateUtils;
import com.gxp.common.utils.DictUtils;
import com.gxp.common.utils.ShiroUtils;
import com.gxp.system.domain.*;
import com.gxp.system.mapper.*;
import com.gxp.system.service.IZknjServiceInstanceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 【请填写功能名称】Service业务层处理
 * 
 * @author zh
 * @date 2024-08-08
 */
@Service
public class ZknjServiceInstanceServiceImpl implements IZknjServiceInstanceService
{
    @Autowired
    private ZknjServiceInstanceMapper serviceInstanceMapper;
    @Autowired
    private ZkAutoExpinfoMapper autoExpinfoMapper;
    @Autowired
    private ZknjRequestMapper requestMapper;
    @Autowired
    private ZknjReqSamInfMapper zknjReqSamInfMapper;
    @Autowired
    private ZkPendingExpMapper zkPendingExpMapper;
    @Autowired
    private ZkNmrFileMapper nmrFileMapper;
    @Autowired
    private ZknjServiceApproveMapper serviceApproveMapper;
    @Autowired
    private ZknjBadgeMapper zknjBadgeMapper;
    @Autowired
    private SysUserMapper sysUserMapper;

    /**
     * 查询【请填写功能名称】
     * 
     * @param infId 【请填写功能名称】主键
     * @return 【请填写功能名称】
     */
    @Override
    public ZknjServiceInstance selectZknjServiceInstanceByInfId(Long infId)
    {
        return serviceInstanceMapper.selectZknjServiceInstanceByInfId(infId);
    }

    /**
     * 查询【请填写功能名称】列表
     * 
     * @param zknjInformation 【请填写功能名称】
     * @return 【请填写功能名称】
     */
    @Override
    public List<ZknjServiceInstance> selectZknjServiceInstanceList(ZknjServiceInstance zknjInformation)
    {
        return serviceInstanceMapper.selectZknjServiceInstanceList(zknjInformation);
    }

    /**
     * 新增【请填写功能名称】
     * 
     * @param zknjInformation 【请填写功能名称】
     * @return 结果
     */
    @Override
    public int insertZknjServiceInstance(ZknjServiceInstance zknjInformation)
    {
        zknjInformation.setCreateTime(DateUtils.getNowDate());
        return serviceInstanceMapper.insertZknjServiceInstance(zknjInformation);
    }

    /**
     * 修改【请填写功能名称】
     * 
     * @param zknjInformation 【请填写功能名称】
     * @return 结果
     */
    @Override
    public int updateZknjServiceInstance(ZknjServiceInstance zknjInformation)
    {
        zknjInformation.setUpdateTime(DateUtils.getNowDate());
        return serviceInstanceMapper.updateZknjServiceInstance(zknjInformation);
    }

    /**
     * 批量删除【请填写功能名称】
     * 
     * @param infIds 需要删除的【请填写功能名称】主键
     * @return 结果
     */
    @Override
    public int deleteZknjServiceInstanceByInfIds(String infIds)
    {
        return serviceInstanceMapper.deleteZknjServiceInstanceByInfIds(Convert.toStrArray(infIds));
    }

    /**
     * 删除【请填写功能名称】信息
     * 
     * @param infId 【请填写功能名称】主键
     * @return 结果
     */
    @Override
    public int deleteZknjServiceInstanceByInfId(Long infId)
    {
        return serviceInstanceMapper.deleteZknjServiceInstanceByInfId(infId);
    }

    /**
     * 根据reqId查询服务申请信息
     * @param reqId
     * @return
     */
    @Override
    public List<ZknjServiceInstance> selectListByReqId(Long reqId) {
        List<ZknjServiceInstance> zknjServiceInstances = serviceInstanceMapper.selectListByReqId(reqId);
        ZknjRequest zknjRequest = requestMapper.selectZknjRequestByReqId(reqId);
        //审核中非审核人员（AM）不可查看原始文件和PDF报告
        if(checkRoleAndStatus(zknjRequest)){
            for (ZknjServiceInstance zknjServiceInstance : zknjServiceInstances) {
                //添加签名信息
                zknjServiceInstance.setZknjServiceApproves(serviceApproveMapper.selectZknjServiceApproveByExpcode(zknjServiceInstance.getExpcode()));
                //获取所有报告文件
                String reportfileIds = zknjServiceInstance.getReportfileIds();
                if(reportfileIds != null && !reportfileIds.isEmpty()){
                    String[] reportFileIdArray = reportfileIds.split(",");
                    for (String reportFileId : reportFileIdArray) {
                        //如果reportFiles为空则初始化
                        if (zknjServiceInstance.getReportFiles() == null) {
                            zknjServiceInstance.setReportFiles(new ArrayList<>());
                        }
                        zknjServiceInstance.getReportFiles().add(nmrFileMapper.selectZkNmrFileByFileId(Long.valueOf(reportFileId)));
                    }
                }
            }
        }else {
            //如果是实验员或者审核员且状态非审核中，则不返回报告文件
            for (ZknjServiceInstance zknjServiceInstance : zknjServiceInstances) {
                //添加签名信息，如果没有签名信息则返回null
                zknjServiceInstance.setZknjServiceApproves(serviceApproveMapper.selectZknjServiceApproveByExpcode(zknjServiceInstance.getExpcode()));
                zknjServiceInstance.setNmrFile(null);
            }
        }
        return zknjServiceInstances;
    }

    /**
     * 检查角色和状态
     * 角色为审核员，状态为审核中时，返回true
     * 角色为实验员，状态为审核中时，返回false
     * 角色为实验员，状态为其他时，返回true
     * 角色为审核员，状态为其他时，返回false
     * @param zknjRequest
     * @return
     */
    private boolean checkRoleAndStatus(ZknjRequest zknjRequest) {
        //获取当前用户角色
        if(ShiroUtils.getSysUser() == null) {
            return false; //如果用户未登录，直接返回false
        }
        boolean isApprover = Objects.equals(ShiroUtils.getSysUser().getRoles().get(0).getRoleId(), UserConstants.ROLE_MANAGER);
        boolean isPending = zknjRequest.getReqStatus().equals(Long.valueOf(DictUtils.getDictValue("sys_request_status", "pending verification")));
        if (isApprover && isPending) {
            //审核员且状态为审核中
            return true;
        } else if (!isApprover && !isPending) {
            //实验员且状态非审核中
            return true;
        } else if (!isApprover && isPending) {
            //实验员且状态为审核中
            return true;
        }else {
            //审核员且状态非审核中
            return false;
        }
    }

    /**
     * 根据id查询服务申请信息
     * @param infId
     * @return
     */
    @Override
    public ZknjServiceInstance selectByInfId(Long infId) {
        return serviceInstanceMapper.selectByInfId(infId);
    }

    /**
     * 更新Service进程
     */
    @Override
    public void updateProcess() {
        List<ZkAutoExpinfo> autoExpinfos = autoExpinfoMapper.selectAll();
        for (ZkAutoExpinfo autoExpinfo : autoExpinfos) {
            String expCode = autoExpinfo.getExpCode();
            ZknjServiceInstance service = new ZknjServiceInstance();
            service.setExpcode(expCode);
            service.setProcess(Long.valueOf(DictUtils.getDictValue("auto_exp_status", autoExpinfo.getStatus())));
            service.setResMsg("-");
            service.setStartTime(autoExpinfo.getStartTime());
            service.setEndTime(autoExpinfo.getEndTime());
            //Error状态同时修改request状态
            if(autoExpinfo.getStatus().equals(AutomationConstants.AUTO_EXP_STATUS_ERROR)){
                //修改Request状态
                ZknjRequest zknjRequest = new ZknjRequest();
                zknjRequest.setReqId(requestMapper.selectOneByExpcode(expCode).getReqId());
                zknjRequest.setReqStatus(Long.valueOf(DictUtils.getDictValue("sys_request_status","error")));
                requestMapper.updateZknjRequest(zknjRequest);
            }

            //Error状态同时修改Service和Request状态
            //不修改Request状态，改由AM提交
//            if(autoExpinfo.getStatus().equals(AutomationConstants.AUTO_EXP_STATUS_ERROR)){
                //修改Service状态
//                service.setSerStatus(Long.valueOf(DictUtils.getDictValue("sys_service_status","error")));
//            }
//            else if(autoExpinfo.getStatus().equals(AutomationConstants.AUTO_EXP_STATUS_DONE)){
//                service.setSerStatus(Long.valueOf(DictUtils.getDictValue("sys_service_status","Completed")));
//            }
//            else if("error".equals(DictUtils.getDictLabel("sys_service_status", String.valueOf(service.getSerStatus())))){
//                //Error状态的实验需要继续完成实验，修改相应状态
//                service.setSerStatus(Long.valueOf(DictUtils.getDictValue("sys_service_status","processing")));
//                ZknjServiceInstance zknjServiceInstance = serviceInstanceMapper.selectZkServiceInstanceByExpcode(expCode);
//                if(zknjServiceInstance != null){
//                    ZknjRequest zknjRequest = new ZknjRequest();
//                    zknjRequest.setReqId(requestMapper.selectOneByExpcode(expCode).getReqId());
//                    zknjRequest.setReqStatus(Long.valueOf(DictUtils.getDictValue("sys_request_status","pending results")));
//                    requestMapper.updateZknjRequest(zknjRequest);
//                }
//            }
            serviceInstanceMapper.updateServiceInstanceByExpcode(service);
        }

    }

    @Override
    public ZknjServiceInstance selectZkServiceInstanceByExpcode(String expcode) {
        return serviceInstanceMapper.selectZkServiceInstanceByExpcode(expcode);
    }

    /**
     * 查询是否都完成，都完成修改Request状态
     * @param infId
     */
    @Override
    public void checkServiceInstanceStatus(Long infId) {
        ZknjReqSamInf zjs = zknjReqSamInfMapper.selectZknjReqSamByInfId(infId);
        List<ZknjServiceInstance> zknjServiceInstances = selectListByReqId(zjs.getReqId());
        //true代表实验都完成
        boolean allCompleted = zknjServiceInstances.stream()
                .filter(instance -> !infId.equals(instance.getInfId()))
                .allMatch(instance -> instance.getProcess().equals(Long.valueOf(DictUtils.getDictValue("auto_exp_status", "Done"))));

        if (allCompleted) {
            ZknjRequest zknjRequest = new ZknjRequest();
            zknjRequest.setReqId(zjs.getReqId());
            zknjRequest.setReqStatus(Long.valueOf(DictUtils.getDictValue("sys_request_status", "pending verification")));
            requestMapper.updateZknjRequest(zknjRequest);

            ZknjRequest zknjRequest1 = requestMapper.selectZknjRequestByReqId(zjs.getReqId());
            String sampleNames = (zknjRequest1.getSamples() != null)
                    ? zknjRequest1.getSamples().stream()
                    .map(ZknjSample::getSamName)
                    .reduce((s1, s2) -> s1 + ", " + s2)
                    .orElse("No samples")
                    : "No samples";
            //根据project获取审核人员并发送消息通知
            List<SysUser> sysUsers = sysUserMapper.selectUserByProId(zknjRequest1.getProId());
            String managers = sysUsers.stream()
                    .filter(user -> user.getRoles().get(0).getRoleId() == UserConstants.ROLE_VERIFIER)
                    .map(SysUser::getUserName)
                    .reduce((s1, s2) -> s1 + ", " + s2)
                    .orElse("No managers");

            ZknjBadge zknjBadge = new ZknjBadge();
            zknjBadge.setEntity("Samples: " + sampleNames);
            zknjBadge.setStatus("N");
            zknjBadge.setDescription("This service has been successfully completed on request '"
                    + zknjRequest1.getReqName() + "'. Please, click here to check its results.");
            zknjBadge.setUrl("/system/request/");
//            zknjBadge.setCreateBy(ShiroUtils.getLoginName());
//            zknjBadge.setReceiver("waniu05");
            zknjBadge.setReceiver(managers);
            zknjBadge.setCreateTime(DateUtils.getNowDate());
            zknjBadge.setTitle("The request '" + zknjRequest1.getReqName() + "' is completed");
            zknjBadgeMapper.insertZknjBadge(zknjBadge);
            zknjBadge.setReceiver(zknjRequest1.getCreateBy());
            zknjBadgeMapper.insertZknjBadge(zknjBadge);
        }
    }

    /**
     * 提交实验停止请求
     */
    @Override
    public int stopExpReq(Long infId) {
        //提交实验停止请求只需要实验code、仪器hostId
        ZknjServiceInstance zknjServiceInstance = serviceInstanceMapper.selectByInfId(infId);
        String expcode = zknjServiceInstance.getExpcode();
        ZkPendingExp zkPendingExp = new ZkPendingExp();
        zkPendingExp.setExpcode(expcode);
        zkPendingExp.setType(AutomationConstants.EXP_TYPE_STOP);
        zkPendingExp.setHostId(zknjServiceInstance.getInstrument().getHostId());
        return zkPendingExpMapper.insertZkPendingExp(zkPendingExp);
    }

    /**
     * 更新服务实例状态
     * @param expcode
     * @param status
     * @return
     */
    @Override
    public int updateStatusByExpcode(String expcode, long status) {
        ZknjServiceInstance zknjServiceInstance = new ZknjServiceInstance();
        zknjServiceInstance.setExpcode(expcode);
        zknjServiceInstance.setSerStatus(status);
        return serviceInstanceMapper.updateServiceInstanceByExpcode(zknjServiceInstance);
    }
}
